home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Programming / jikes-1.02 / src / definite.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-08-26  |  73.5 KB  |  2,001 lines

  1. // $Id: definite.cpp,v 1.11 1999/08/26 15:34:07 shields Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #include "config.h"
  11. #include <assert.h>
  12. #include <stdio.h>
  13. #include "semantic.h"
  14.  
  15. DefiniteAssignmentSet *Semantic::DefiniteExpression(AstExpression *expr, BitSet &set)
  16. {
  17.     DefiniteAssignmentSet *definite = NULL;
  18.  
  19.     //
  20.     // Is the expression a constant expression of type boolean?
  21.     // Recall that a constant expression may not contain an
  22.     // assignment statement.
  23.     //
  24.     if (expr -> IsConstant() && expr -> Type() == control.boolean_type)
  25.     {
  26.         definite = new DefiniteAssignmentSet(universe -> Size());
  27.         IntLiteralValue *result = (IntLiteralValue *) expr -> value;
  28.         if (result -> value)
  29.         {
  30.             definite -> true_set  = set;
  31.             definite -> false_set = *universe;
  32.         }
  33.         else
  34.         {
  35.             definite -> true_set  = *universe;
  36.             definite -> false_set = set;
  37.         }
  38.     }
  39.     else if (expr -> symbol != control.no_type)
  40.         definite = (this ->* DefiniteExpr[expr -> kind])(expr, set);
  41.  
  42.     return definite;
  43. }
  44.  
  45.  
  46. DefiniteAssignmentSet *Semantic::DefiniteSimpleName(AstExpression *expression, BitSet &set)
  47. {
  48.     AstSimpleName *simple_name = (AstSimpleName *) expression;
  49.  
  50.     if (simple_name -> resolution_opt)
  51.         return DefiniteExpression(simple_name -> resolution_opt, set);
  52.  
  53.     //
  54.     // Some simple names are undefined. e.g., the simple name in a method call.
  55.     //
  56.     VariableSymbol *variable = (simple_name -> symbol ? simple_name -> symbol -> VariableCast() : (VariableSymbol *) NULL);
  57.     if (variable && (variable -> IsLocal(ThisMethod()) || variable -> IsFinal(ThisType())))
  58.     {
  59.         if (! set[variable -> LocalVariableIndex()])
  60.         {
  61.             ReportSemError(SemanticError::VARIABLE_NOT_DEFINITELY_ASSIGNED,
  62.                            simple_name -> identifier_token,
  63.                            simple_name -> identifier_token,
  64.                            variable -> Name());
  65.  
  66.             if (variable -> IsLocal(ThisMethod())) // to avoid cascading errors!
  67.                 set.AddElement(variable -> LocalVariableIndex());
  68.         }
  69.     }
  70.  
  71.     return (DefiniteAssignmentSet *) NULL;
  72. }
  73.  
  74.  
  75. DefiniteAssignmentSet *Semantic::DefiniteArrayAccess(AstExpression *expression, BitSet &set)
  76. {
  77.     AstArrayAccess *array_access = (AstArrayAccess *) expression;
  78.  
  79.     DefiniteAssignmentSet *after_base = DefiniteExpression(array_access -> base, set);
  80.     if (after_base) // if this is true then something is wrong
  81.     {
  82.         set = after_base -> true_set * after_base -> false_set;
  83.         delete after_base;
  84.     }
  85.  
  86.     DefiniteAssignmentSet *after_expr = DefiniteExpression(array_access -> expression, set);
  87.     if (after_expr) // if this is true then something is wrong
  88.     {
  89.         set = after_expr -> true_set * after_expr -> false_set;
  90.         delete after_expr;
  91.     }
  92.  
  93.     return (DefiniteAssignmentSet *) NULL;
  94. }
  95.  
  96.  
  97. DefiniteAssignmentSet *Semantic::DefiniteMethodInvocation(AstExpression *expression, BitSet &set)
  98. {
  99.     AstMethodInvocation *method_call = (AstMethodInvocation *) expression;
  100.  
  101.     DefiniteAssignmentSet *after_method = DefiniteExpression(method_call -> method, set);
  102.     if (after_method)
  103.     {
  104.         set = after_method -> true_set * after_method -> false_set;
  105.         delete after_method;
  106.     }
  107.  
  108.     for (int i = 0; i < method_call -> NumArguments(); i++)
  109.     {
  110.         AstExpression *expr = method_call -> Argument(i);
  111.         DefiniteAssignmentSet *after_expr = DefiniteExpression(expr, set);
  112.         if (after_expr)
  113.         {
  114.             set = after_expr -> true_set * after_expr -> false_set;
  115.             delete after_expr;
  116.         }
  117.     }
  118.  
  119.     return (DefiniteAssignmentSet *) NULL;
  120. }
  121.  
  122.  
  123. DefiniteAssignmentSet *Semantic::DefiniteClassInstanceCreationExpression(AstExpression *expression, BitSet &set)
  124. {
  125.     AstClassInstanceCreationExpression *class_creation = (AstClassInstanceCreationExpression *) expression;
  126.  
  127.     if (class_creation -> base_opt)
  128.     {
  129.         DefiniteAssignmentSet *after_expr = DefiniteExpression(class_creation -> base_opt, set);
  130.         if (after_expr)
  131.         {
  132.             set = after_expr -> true_set * after_expr -> false_set;
  133.             delete after_expr;
  134.         }
  135.     }
  136.  
  137.     for (int i = 0; i < class_creation -> NumLocalArguments(); i++)
  138.     {
  139.         AstExpression *expr = class_creation -> LocalArgument(i);
  140.         DefiniteAssignmentSet *after_expr = DefiniteExpression(expr, set);
  141.         if (after_expr)
  142.         {
  143.             set = after_expr -> true_set * after_expr -> false_set;
  144.             delete after_expr;
  145.         }
  146.     }
  147.  
  148.     for (int k = 0; k < class_creation -> NumArguments(); k++)
  149.     {
  150.         AstExpression *expr = class_creation -> Argument(k);
  151.         DefiniteAssignmentSet *after_expr = DefiniteExpression(expr, set);
  152.         if (after_expr)
  153.         {
  154.             set = after_expr -> true_set * after_expr -> false_set;
  155.             delete after_expr;
  156.         }
  157.     }
  158.  
  159.     return (DefiniteAssignmentSet *) NULL;
  160. }
  161.  
  162.  
  163. DefiniteAssignmentSet *Semantic::DefiniteArrayCreationExpression(AstExpression *expression, BitSet &set)
  164. {
  165.     AstArrayCreationExpression *array_creation = (AstArrayCreationExpression *) expression;
  166.  
  167.     for (int i = 0; i < array_creation -> NumDimExprs(); i++)
  168.     {
  169.         AstDimExpr *dim_expr = array_creation -> DimExpr(i);
  170.         DefiniteAssignmentSet *after_expr = DefiniteExpression(dim_expr -> expression, set);
  171.         if (after_expr)
  172.         {
  173.             set = after_expr -> true_set * after_expr -> false_set;
  174.             delete after_expr;
  175.         }
  176.     }
  177.  
  178.     if (array_creation -> array_initializer_opt)
  179.         DefiniteArrayInitializer(array_creation -> array_initializer_opt);
  180.  
  181.     return (DefiniteAssignmentSet *) NULL;
  182. }
  183.  
  184.  
  185. inline VariableSymbol *Semantic::DefiniteFinal(AstFieldAccess *field_access)
  186. {
  187.     if (field_access -> resolution_opt)
  188.         field_access = field_access -> resolution_opt -> FieldAccessCast();
  189.  
  190.     if (field_access)
  191.     {
  192.         VariableSymbol *variable = (field_access -> symbol ? field_access -> symbol -> VariableCast() : (VariableSymbol *) NULL);
  193.         if (variable && variable -> IsFinal(ThisType()))
  194.         {
  195.             if (variable -> ACC_STATIC()) // there is exactly one copy of a static variable, so, it's always the right one.
  196.                 return variable;
  197.  
  198.             AstFieldAccess *sub_field_access = field_access -> base -> FieldAccessCast();
  199.             if (field_access -> base -> ThisExpressionCast() || (sub_field_access && sub_field_access -> IsThisAccess()))
  200.                 return variable;
  201.         }
  202.     }
  203.  
  204.     return NULL;
  205. }
  206.  
  207.  
  208. DefiniteAssignmentSet *Semantic::DefinitePLUSPLUSOrMINUSMINUS(AstExpression *expr, BitSet &set)
  209. {
  210.     DefiniteAssignmentSet *definite = DefiniteExpression(expr, set);
  211.     if (definite) // if this is true then something is wrong
  212.     {
  213.         set = definite -> true_set * definite -> false_set;
  214.         delete definite;
  215.     }
  216.  
  217.     VariableSymbol *variable = NULL;
  218.     if (! expr -> ArrayAccessCast()) // some kind of name
  219.     {
  220.         MethodSymbol *read_method = NULL;
  221.         AstSimpleName *simple_name = expr -> SimpleNameCast();
  222.         if (simple_name)
  223.         {
  224.             if (simple_name -> resolution_opt)
  225.                read_method = simple_name -> resolution_opt -> symbol -> MethodCast();
  226.         }
  227.         else
  228.         {
  229.             AstFieldAccess *field_access = expr -> FieldAccessCast();
  230.  
  231.             assert(field_access);
  232.  
  233.             if (field_access -> resolution_opt)
  234.                 read_method = field_access -> resolution_opt -> symbol -> MethodCast();
  235.         }
  236.  
  237.         variable = (read_method ? (VariableSymbol *) read_method -> accessed_member : expr -> symbol -> VariableCast());
  238.     }
  239.  
  240.     //
  241.     // If we have a variable and it is final then...
  242.     //
  243.     if (variable && variable -> ACC_FINAL())
  244.     {
  245.         ReportSemError(SemanticError::TARGET_VARIABLE_IS_FINAL,
  246.                        expr -> LeftToken(),
  247.                        expr -> RightToken(),
  248.                        variable -> Name());
  249.  
  250.         if (variable -> IsFinal(ThisType())) // if the final variable in contained in this type, then mark it assigned
  251.             possibly_assigned_finals -> AddElement(variable -> LocalVariableIndex());
  252.     }
  253.  
  254.     return (DefiniteAssignmentSet *) NULL;
  255. }
  256.  
  257.  
  258. DefiniteAssignmentSet *Semantic::DefinitePostUnaryExpression(AstExpression *expression, BitSet &set)
  259. {
  260.     AstPostUnaryExpression *postfix_expression = (AstPostUnaryExpression *) expression;
  261.     return DefinitePLUSPLUSOrMINUSMINUS(postfix_expression -> expression, set);
  262. }
  263.  
  264.  
  265. DefiniteAssignmentSet *Semantic::DefiniteNOT(AstExpression *expr, BitSet &set)
  266. {
  267.     DefiniteAssignmentSet *after_expr = DefiniteExpression(expr, set);
  268.     if (after_expr) // is the expression is a complex boolean expression?
  269.     {
  270.         BitSet temp(after_expr -> true_set);
  271.         after_expr -> true_set = after_expr -> false_set;
  272.         after_expr -> false_set = temp;
  273.     }
  274.  
  275.     return after_expr;
  276. }
  277.  
  278.  
  279. //
  280. // The default pre unary operators are +, -, and ~.
  281. // As these operators are not applicable to boolean expressions,
  282. // we do not need to invoke DefiniteExpression to process them.
  283. //
  284. DefiniteAssignmentSet *Semantic::DefiniteDefaultPreUnaryExpression(AstExpression *expr, BitSet &set)
  285. {
  286.     return (this ->* DefiniteExpr[expr -> kind])(expr, set);
  287. }
  288.  
  289.  
  290. DefiniteAssignmentSet *Semantic::DefinitePreUnaryExpression(AstExpression *expression, BitSet &set)
  291. {
  292.     AstPreUnaryExpression *prefix_expression = (AstPreUnaryExpression *) expression;
  293.     return (this ->* DefinitePreUnaryExpr[prefix_expression -> pre_unary_tag])(prefix_expression -> expression, set);
  294. }
  295.  
  296.  
  297. DefiniteAssignmentSet *Semantic::DefiniteAssignmentAND(TypeSymbol *type,
  298.                                                        BitSet *before_right,
  299.                                                        BitSet &set,
  300.                                                        DefiniteAssignmentSet *after_left,
  301.                                                        DefiniteAssignmentSet *after_right)
  302. {
  303.     if (after_left || after_right) // one of the subexpressions is a complex boolean expression
  304.     {
  305.         if (! after_left)
  306.         {
  307.             after_left = new DefiniteAssignmentSet(universe -> Size());
  308.             after_left -> true_set = *before_right;
  309.             after_left -> false_set = *before_right;
  310.         }
  311.  
  312.         if (! after_right)
  313.         {
  314.             after_right = new DefiniteAssignmentSet(universe -> Size());
  315.             after_right -> true_set = set;
  316.             after_right -> false_set = set;
  317.         }
  318.  
  319.         after_left -> true_set += after_right -> true_set;   // definitely assigned after left when true and after right when true
  320.         after_left -> false_set *= after_right -> false_set; // definitely assigned after left when false and after right when false
  321.         after_right -> true_set *= after_right -> false_set; // definitely assigned after right
  322.         after_left -> false_set += after_right -> true_set;
  323.  
  324.         delete after_right;
  325.     }
  326.  
  327.     delete before_right; // nothing happens if before_right is null
  328.  
  329.     return after_left;
  330. }
  331.  
  332.  
  333. DefiniteAssignmentSet *Semantic::DefiniteAssignmentIOR(TypeSymbol *type,
  334.                                                        BitSet *before_right,
  335.                                                        BitSet &set,
  336.                                                        DefiniteAssignmentSet *after_left,
  337.                                                        DefiniteAssignmentSet *after_right)
  338. {
  339.     if (after_left || after_right) // one of the subexpressions is a complex boolean expression
  340.     {
  341.         if (! after_left)
  342.         {
  343.             after_left = new DefiniteAssignmentSet(universe -> Size());
  344.             after_left -> true_set = *before_right;
  345.             after_left -> false_set = *before_right;
  346.         }
  347.  
  348.         if (! after_right)
  349.         {
  350.             after_right = new DefiniteAssignmentSet(universe -> Size());
  351.             after_right -> true_set = set;
  352.             after_right -> false_set = set;
  353.         }
  354.  
  355.         after_left -> true_set *= after_right -> true_set;   // after a when true and after b when true
  356.         after_right -> true_set *= after_right -> false_set; // definitely assigned after b
  357.         after_left -> true_set += after_right -> true_set;
  358.         after_left -> false_set += after_right -> false_set; // after a when false or after b when false
  359.  
  360.         delete after_right;
  361.     }
  362.  
  363.     delete before_right; // nothing happens if before_right is null
  364.  
  365.     return after_left;
  366. }
  367.  
  368.  
  369. DefiniteAssignmentSet *Semantic::DefiniteAssignmentXOR(TypeSymbol *type,
  370.                                                        BitSet *before_right,
  371.                                                        BitSet &set,
  372.                                                        DefiniteAssignmentSet *after_left,
  373.                                                        DefiniteAssignmentSet *after_right)
  374. {
  375.     DefiniteAssignmentSet *definite = NULL;
  376.  
  377.     if (after_left || after_right) // one of the subexpressions is a complex boolean expression
  378.     {
  379.         definite = new DefiniteAssignmentSet(universe -> Size());
  380.  
  381.         if (! after_left)
  382.         {
  383.             after_left = new DefiniteAssignmentSet(universe -> Size());
  384.             after_left -> true_set = *before_right;
  385.             after_left -> false_set = *before_right;
  386.         }
  387.  
  388.         if (! after_right)
  389.         {
  390.             after_right = new DefiniteAssignmentSet(universe -> Size());
  391.             after_right -> true_set = set;
  392.             after_right -> false_set = set;
  393.         }
  394.  
  395.         //
  396.         // compute definitely assigned after right.
  397.         //
  398.         definite -> true_set = definite -> false_set = (after_right -> true_set * after_right -> false_set);
  399.  
  400.         //
  401.         // compute definitely assigned after left when true and after right when true
  402.         // compute definitely assigned after left when false and after right when false
  403.         // add the union of these two sets to true_set;
  404.         //
  405.         definite -> true_set += (after_left -> true_set * after_right -> true_set)
  406.                               + (after_left -> false_set * after_right -> false_set);
  407.         //
  408.         // compute definitely assigned after left when true and after right when false
  409.         // compute definitely assigned after left when false and after right when true
  410.         // add the union of these two sets to false_set;
  411.         //
  412.         definite -> false_set += (after_left -> true_set * after_right -> false_set)
  413.                                + (after_left -> false_set * after_right -> true_set);
  414.  
  415.         delete after_left;
  416.         delete after_right;
  417.     }
  418.  
  419.     delete before_right;  // nothing happens if before_right is NULL
  420.  
  421.     return definite;
  422. }
  423.  
  424.  
  425. DefiniteAssignmentSet *Semantic::DefiniteAND(AstBinaryExpression *expr, BitSet &set)
  426. {
  427.     DefiniteAssignmentSet *after_left = DefiniteExpression(expr -> left_expression, set);
  428.     BitSet *before_right = NULL;
  429.     if (after_left)
  430.          set = after_left -> true_set * after_left -> false_set;
  431.     else before_right = new BitSet(set);
  432.     DefiniteAssignmentSet *after_right = DefiniteExpression(expr -> right_expression, set);
  433.  
  434.     return DefiniteAssignmentAND(expr -> left_expression -> Type(), before_right, set, after_left, after_right);
  435. }
  436.  
  437.  
  438. DefiniteAssignmentSet *Semantic::DefiniteIOR(AstBinaryExpression *expr, BitSet &set)
  439. {
  440.     DefiniteAssignmentSet *after_left = DefiniteExpression(expr -> left_expression, set);
  441.     BitSet *before_right = NULL;
  442.     if (after_left)
  443.          set = after_left -> true_set * after_left -> false_set;
  444.     else before_right = new BitSet(set);
  445.     DefiniteAssignmentSet *after_right = DefiniteExpression(expr -> right_expression, set);
  446.  
  447.     return DefiniteAssignmentIOR(expr -> left_expression -> Type(), before_right, set, after_left, after_right);
  448. }
  449.  
  450.  
  451. DefiniteAssignmentSet *Semantic::DefiniteXOR(AstBinaryExpression *expr, BitSet &set)
  452. {
  453.     DefiniteAssignmentSet *after_left = DefiniteExpression(expr -> left_expression, set);
  454.     BitSet *before_right = NULL;
  455.     if (after_left)
  456.          set = after_left -> true_set * after_left -> false_set;
  457.     else before_right = new BitSet(set);
  458.     DefiniteAssignmentSet *after_right = DefiniteExpression(expr -> right_expression, set);
  459.  
  460.     return DefiniteAssignmentXOR(expr -> left_expression -> Type(), before_right, set, after_left, after_right);
  461. }
  462.  
  463.  
  464. DefiniteAssignmentSet *Semantic::DefiniteAND_AND(AstBinaryExpression *expr, BitSet &set)
  465. {
  466.     DefiniteAssignmentSet *after_left = DefiniteExpression(expr -> left_expression, set);
  467.     BitSet *before_right = NULL;
  468.     if (after_left)
  469.          set = after_left -> true_set;
  470.     else before_right = new BitSet(set);
  471.     DefiniteAssignmentSet *after_right = DefiniteExpression(expr -> right_expression, set);
  472.  
  473.     if (after_left)
  474.     {
  475.         if (after_right)
  476.         {
  477.             after_left -> true_set += after_right -> true_set;
  478.             after_left -> false_set *= after_right -> false_set;
  479.             delete after_right;
  480.         }
  481.         else
  482.         {
  483.             after_left -> true_set += set;
  484.             after_left -> false_set *= set;
  485.         }
  486.  
  487.         after_right = after_left;
  488.     }
  489.     else
  490.     {
  491.         if (! after_right)
  492.         {
  493.             after_right = new DefiniteAssignmentSet(universe -> Size());
  494.  
  495.             after_right -> true_set = set;
  496.             after_right -> false_set = set;
  497.         }
  498.         after_right -> true_set += *before_right;
  499.         after_right -> false_set *= *before_right;
  500.  
  501.         delete before_right;
  502.     }
  503.  
  504.     return after_right;
  505. }
  506.  
  507.  
  508. DefiniteAssignmentSet *Semantic::DefiniteOR_OR(AstBinaryExpression *expr, BitSet &set)
  509. {
  510.     DefiniteAssignmentSet *after_left = DefiniteExpression(expr -> left_expression, set);
  511.     BitSet *before_right = NULL;
  512.     if (after_left)
  513.          set = after_left -> false_set;
  514.     else before_right = new BitSet(set);
  515.     DefiniteAssignmentSet *after_right = DefiniteExpression(expr -> right_expression, set);
  516.  
  517.     if (after_left)
  518.     {
  519.         if (after_right)
  520.         {
  521.             after_left -> true_set *= after_right -> true_set;
  522.             after_left -> false_set += after_right -> false_set;
  523.             delete after_right;
  524.         }
  525.         else
  526.         {
  527.             after_left -> true_set *= set;
  528.             after_left -> false_set += set;
  529.         }
  530.  
  531.         after_right = after_left;
  532.     }
  533.     else
  534.     {
  535.         if (! after_right)
  536.         {
  537.             after_right = new DefiniteAssignmentSet(universe -> Size());
  538.  
  539.             after_right -> true_set = set;
  540.             after_right -> false_set = set;
  541.         }
  542.         after_right -> true_set *= *before_right;
  543.         after_right -> false_set += *before_right;
  544.  
  545.         delete before_right;
  546.     }
  547.  
  548.     return after_right;
  549. }
  550.  
  551.  
  552. DefiniteAssignmentSet *Semantic::DefiniteEQUAL_EQUAL(AstBinaryExpression *expr, BitSet &set)
  553. {
  554.     DefiniteAssignmentSet *after_left = DefiniteExpression(expr -> left_expression, set);
  555.     BitSet *before_right = NULL;
  556.     if (after_left)
  557.          set = after_left -> true_set * after_left -> false_set;
  558.     else before_right = new BitSet(set);
  559.     DefiniteAssignmentSet *after_right = DefiniteExpression(expr -> right_expression, set);
  560.  
  561.     DefiniteAssignmentSet *definite = NULL;
  562.  
  563.     if (after_left || after_right) // one of the subexpressions is a complex boolean expression
  564.     {
  565.         definite = new DefiniteAssignmentSet(universe -> Size());
  566.  
  567.         if (! after_left)
  568.         {
  569.             after_left = new DefiniteAssignmentSet(universe -> Size());
  570.             after_left -> true_set = *before_right;
  571.             after_left -> false_set = *before_right;
  572.         }
  573.  
  574.         if (! after_right)
  575.         {
  576.             after_right = new DefiniteAssignmentSet(universe -> Size());
  577.             after_right -> true_set = set;
  578.             after_right -> false_set = set;
  579.         }
  580.  
  581.         //
  582.         // compute definitely assigned after right.
  583.         //
  584.         definite -> true_set = definite -> false_set = (after_right -> true_set * after_right -> false_set);
  585.  
  586.         //
  587.         // compute definitely assigned after left when true and after right when false
  588.         // compute definitely assigned after left when false and after right when true
  589.         // and add their union to true_set
  590.         //
  591.         definite -> true_set += (after_left -> true_set * after_right -> false_set)
  592.                               + (after_left -> false_set * after_right -> true_set);
  593.  
  594.         //
  595.         // compute definitely assigned after left when true and after right when true
  596.         // compute definitely assigned after left when false and after right when false
  597.         // and add their union to false_set
  598.         //
  599.         definite -> false_set += (after_left -> true_set * after_right -> true_set)
  600.                                + (after_left -> false_set * after_right -> false_set);
  601.  
  602.         delete after_left;
  603.         delete after_right;
  604.     }
  605.  
  606.     delete before_right; // nothing happens if before_right is NULL
  607.  
  608.     return definite;
  609. }
  610.  
  611.  
  612. DefiniteAssignmentSet *Semantic::DefiniteNOT_EQUAL(AstBinaryExpression *expr, BitSet &set)
  613. {
  614.     DefiniteAssignmentSet *after_left = DefiniteExpression(expr -> left_expression, set);
  615.     BitSet *before_right = NULL;
  616.     if (after_left)
  617.          set = after_left -> true_set * after_left -> false_set;
  618.     else before_right = new BitSet(set);
  619.     DefiniteAssignmentSet *after_right = DefiniteExpression(expr -> right_expression, set);
  620.  
  621.     //
  622.     // NOT_EQUAL has same definite assignment rules as XOR
  623.     //
  624.     return DefiniteAssignmentXOR(expr -> left_expression -> Type(), before_right, set, after_left, after_right);
  625. }
  626.  
  627.  
  628. DefiniteAssignmentSet *Semantic::DefiniteDefaultBinaryExpression(AstBinaryExpression *expr, BitSet &set)
  629. {
  630.     DefiniteAssignmentSet *after_left = DefiniteExpression(expr -> left_expression, set);
  631.     if (after_left) // if this is true there was a mistake !!!
  632.     {
  633.         set = after_left -> true_set * after_left -> false_set;
  634.         delete after_left;
  635.     }
  636.  
  637.     DefiniteAssignmentSet *after_right = DefiniteExpression(expr -> right_expression, set);
  638.     if (after_right) // if this is true there was a mistake !!!
  639.     {
  640.         set = (after_right -> true_set * after_right -> false_set);
  641.         delete after_right;
  642.     }
  643.  
  644.     return (DefiniteAssignmentSet *) NULL;
  645. }
  646.  
  647.  
  648. DefiniteAssignmentSet *Semantic::DefiniteBinaryExpression(AstExpression *expression, BitSet &set)
  649. {
  650.     AstBinaryExpression *binary_expression = (AstBinaryExpression *) expression;
  651.     return (this ->* DefiniteBinaryExpr[binary_expression -> binary_tag])(binary_expression, set);
  652. }
  653.  
  654.  
  655. DefiniteAssignmentSet *Semantic::DefiniteConditionalExpression(AstExpression *expression, BitSet &set)
  656. {
  657.     AstConditionalExpression *conditional_expression = (AstConditionalExpression *) expression;
  658.  
  659.     DefiniteAssignmentSet *after_condition = DefiniteExpression(conditional_expression -> test_expression, set);
  660.     BitSet *before_expressions = NULL;
  661.  
  662.     if (after_condition)
  663.          set = after_condition -> true_set;
  664.     else before_expressions = new BitSet(set);
  665.     DefiniteAssignmentSet *after_true = DefiniteExpression(conditional_expression -> true_expression, set);
  666.     BitSet *after_true_set = (BitSet *) (after_true ? NULL : new BitSet(set));
  667.  
  668.     if (after_condition)
  669.          set = after_condition -> false_set;
  670.     else set = *before_expressions;
  671.     DefiniteAssignmentSet *after_false = DefiniteExpression(conditional_expression -> false_expression, set);
  672.  
  673.     DefiniteAssignmentSet *definite = NULL;
  674.  
  675.     if (conditional_expression -> Type() == control.boolean_type)
  676.     {
  677.         definite = new DefiniteAssignmentSet(universe -> Size());
  678.  
  679.         //
  680.         //
  681.         //
  682.         if (after_true)
  683.         {
  684.             //
  685.             // before "true" expr or after it when true
  686.             //
  687.             definite -> true_set = after_true -> true_set + (after_condition ? after_condition -> true_set : *before_expressions);
  688.         }
  689.         else definite -> true_set = *after_true_set;
  690.  
  691.         if (after_false)
  692.         {
  693.             //
  694.             // before "false" expr or after it when true
  695.             //
  696.             definite -> true_set *= (after_false -> true_set +
  697.                                     (after_condition ? after_condition -> false_set : *before_expressions));
  698.         }
  699.         else definite -> true_set *= set;
  700.  
  701.         //
  702.         //
  703.         //
  704.         if (after_true)
  705.         {
  706.             //
  707.             // before "true" expr or after it when false
  708.             //
  709.             definite -> false_set = after_true -> false_set + (after_condition ? after_condition -> true_set : *before_expressions);
  710.         }
  711.         else definite -> false_set = *after_true_set;
  712.  
  713.         if (after_false)
  714.         {
  715.             //
  716.             // before "false" expr or after it when true
  717.             //
  718.             definite -> true_set *= (after_false -> false_set +
  719.                                      (after_condition ? after_condition -> false_set : *before_expressions));
  720.         }
  721.         else definite -> false_set *= set;
  722.     }
  723.     else
  724.     {
  725.         if (after_false)
  726.             set = after_false -> true_set * after_false -> false_set; // definitely assigned after the false expression ...
  727.  
  728.         // ... and definitely assigned after the true expression
  729.         if (after_true)
  730.              set *= (after_true -> true_set * after_true -> false_set);
  731.         else set *= *after_true_set;
  732.     }
  733.  
  734.     delete after_condition;    // nothing happens if after_condition is NULL
  735.     delete before_expressions; // nothing happens if before_expressions is NULL
  736.     delete after_true;         // nothing happens if after_true is NULL
  737.     delete after_true_set;     // nothing happens if after_true_set is NULL
  738.     delete after_false;        // nothing happens if after_false is NULL
  739.  
  740.     return definite;
  741. }
  742.  
  743.  
  744. DefiniteAssignmentSet *Semantic::DefiniteAssignmentExpression(AstExpression *expression, BitSet &set)
  745. {
  746.     AstAssignmentExpression *assignment_expression = (AstAssignmentExpression *) expression;
  747.  
  748.     AstExpression *left_hand_side = assignment_expression -> left_hand_side;
  749.     AstSimpleName *simple_name = left_hand_side -> SimpleNameCast();
  750.     if (simple_name)
  751.     {
  752.         if (simple_name -> resolution_opt)
  753.         {
  754.             left_hand_side = simple_name -> resolution_opt;
  755.             simple_name = left_hand_side -> SimpleNameCast();
  756.         }
  757.     }
  758.     else
  759.     {
  760.         AstFieldAccess *field_access = left_hand_side -> FieldAccessCast();
  761.         if (field_access && field_access -> resolution_opt)
  762.             left_hand_side = field_access -> resolution_opt;
  763.     }
  764.  
  765.     VariableSymbol *variable = (left_hand_side -> symbol ? left_hand_side -> symbol -> VariableCast() : (VariableSymbol *) NULL);
  766.  
  767.     //
  768.     // An array access is never considered to be final. Since no variable
  769.     // is associated with the array access, the testing for the presence of variable
  770.     // takes care of that possibility.
  771.     //
  772.     if (variable)
  773.     {
  774.         if (variable -> IsLocal(ThisMethod()) || variable -> IsFinal(ThisType()))
  775.         {
  776.             if (assignment_expression -> assignment_tag != AstAssignmentExpression::EQUAL &&
  777.                 (! set[variable -> LocalVariableIndex()]))
  778.             {
  779.                 ReportSemError(SemanticError::VARIABLE_NOT_DEFINITELY_ASSIGNED,
  780.                                assignment_expression -> left_hand_side -> LeftToken(),
  781.                                assignment_expression -> left_hand_side -> RightToken(),
  782.                                variable -> Name());
  783.             }
  784.             else if (variable -> ACC_FINAL())
  785.             {
  786.                 //
  787.                 // If the final variable may have already been initialized, issue an error.
  788.                 //
  789.                 if ((assignment_expression -> assignment_tag != AstAssignmentExpression::EQUAL) ||
  790.                     ((*possibly_assigned_finals) [variable -> LocalVariableIndex()]))
  791.                 {
  792.                     ReportSemError(SemanticError::TARGET_VARIABLE_IS_FINAL,
  793.                                    assignment_expression -> left_hand_side -> LeftToken(),
  794.                                    assignment_expression -> left_hand_side -> RightToken(),
  795.                                    variable -> Name());
  796.                 }
  797.                 else if (definite_final_assignment_stack -> Size() > 0) // are we processing the body of a loop ?
  798.                      definite_final_assignment_stack -> Top().Next() = left_hand_side;
  799.             }
  800.         }
  801.         else if (variable -> ACC_FINAL()) // attempt to assign a value to a final field member!
  802.         {
  803.             ReportSemError(SemanticError::TARGET_VARIABLE_IS_FINAL,
  804.                            assignment_expression -> left_hand_side -> LeftToken(),
  805.                            assignment_expression -> left_hand_side -> RightToken(),
  806.                            variable -> Name());
  807.         }
  808.     }
  809.  
  810.     DefiniteAssignmentSet *after_left = NULL;
  811.     BitSet *before_right = NULL;
  812.     //
  813.     // The left-hand-side of an assignment expression is either a simple name,
  814.     // a field access or an array access.
  815.     //
  816.     if (! simple_name)
  817.     {
  818.         AstFieldAccess *field_access = left_hand_side -> FieldAccessCast();
  819.         after_left = DefiniteExpression((field_access ? field_access -> base : left_hand_side), set);
  820.     }
  821.  
  822.     if (after_left)
  823.          set = after_left -> true_set * after_left -> false_set;
  824.     else before_right = new BitSet(set);
  825.  
  826.     DefiniteAssignmentSet *after_right = DefiniteExpression(assignment_expression -> expression, set);
  827.  
  828.     if (left_hand_side -> Type() == control.boolean_type)
  829.     {
  830.         DefiniteAssignmentSet *definite = NULL;
  831.  
  832.         if (assignment_expression -> assignment_tag == AstAssignmentExpression::AND_EQUAL)
  833.              definite = DefiniteAssignmentAND(control.boolean_type, before_right, set, after_left, after_right);
  834.         else if (assignment_expression -> assignment_tag == AstAssignmentExpression::XOR_EQUAL)
  835.              definite = DefiniteAssignmentXOR(control.boolean_type, before_right, set, after_left, after_right);
  836.         else if (assignment_expression -> assignment_tag == AstAssignmentExpression::IOR_EQUAL)
  837.              definite = DefiniteAssignmentIOR(control.boolean_type, before_right, set, after_left, after_right);
  838.         else
  839.         {
  840.             delete after_left;
  841.             delete before_right;
  842.             definite = after_right;
  843.         }
  844.  
  845.         if (variable && (variable -> IsLocal(ThisMethod()) || variable -> IsFinal(ThisType())))
  846.         {
  847.             if (definite)
  848.             {
  849.                 definite -> true_set.AddElement(variable -> LocalVariableIndex());
  850.                 definite -> false_set.AddElement(variable -> LocalVariableIndex());
  851.             }
  852.             else set.AddElement(variable -> LocalVariableIndex());
  853.  
  854.             if (variable -> ACC_FINAL())
  855.                 possibly_assigned_finals -> AddElement(variable -> LocalVariableIndex());
  856.         }
  857.  
  858.         return definite;
  859.     }
  860.  
  861.     if (after_right)
  862.         set = after_right -> true_set * after_right -> false_set;
  863.  
  864.     if (variable && (variable -> IsLocal(ThisMethod()) || variable -> IsFinal(ThisType())))
  865.     {
  866.         set.AddElement(variable -> LocalVariableIndex());
  867.         if (variable -> ACC_FINAL())
  868.             possibly_assigned_finals -> AddElement(variable -> LocalVariableIndex());
  869.     }
  870.  
  871.     delete after_left;   // nothing happens if after_left is NULL
  872.     delete before_right; // nothing happens if before_right is NULL
  873.     delete after_right;  // nothing happens if after_right is NULL
  874.  
  875.     return (DefiniteAssignmentSet *) NULL;
  876. }
  877.  
  878. DefiniteAssignmentSet *Semantic::DefiniteDefaultExpression(AstExpression *expr, BitSet &set)
  879. {
  880.     return (DefiniteAssignmentSet *) NULL;
  881. }
  882.  
  883. DefiniteAssignmentSet *Semantic::DefiniteParenthesizedExpression(AstExpression *expression, BitSet &set)
  884. {
  885.     AstParenthesizedExpression *expr = (AstParenthesizedExpression *) expression;
  886.  
  887.     return DefiniteExpression(expr -> expression, set);
  888. }
  889.  
  890. DefiniteAssignmentSet *Semantic::DefiniteFieldAccess(AstExpression *expression, BitSet &set)
  891. {
  892.     AstFieldAccess *expr = (AstFieldAccess *) expression;
  893.  
  894.     VariableSymbol *variable = DefiniteFinal(expr);
  895.     if (variable)
  896.     {
  897.         if (! set[variable -> LocalVariableIndex()])
  898.         {
  899.             ReportSemError(SemanticError::VARIABLE_NOT_DEFINITELY_ASSIGNED,
  900.                            expr -> LeftToken(),
  901.                            expr -> RightToken(),
  902.                            variable -> Name());
  903.             set.AddElement(variable -> LocalVariableIndex());
  904.         }
  905.     }
  906.  
  907.     return DefiniteExpression((expr -> resolution_opt ? expr -> resolution_opt : expr -> base), set);
  908. }
  909.  
  910. DefiniteAssignmentSet *Semantic::DefiniteCastExpression(AstExpression *expression, BitSet &set)
  911. {
  912.     AstCastExpression *expr = (AstCastExpression *) expression;
  913.  
  914.     return DefiniteExpression(expr -> expression, set);
  915. }
  916.  
  917. void Semantic::DefiniteArrayInitializer(AstArrayInitializer *array_initializer)
  918. {
  919.     for (int i = 0; i < array_initializer -> NumVariableInitializers(); i++)
  920.     {
  921.         AstArrayInitializer *sub_array_initializer = array_initializer -> VariableInitializer(i) -> ArrayInitializerCast();
  922.  
  923.         if (sub_array_initializer)
  924.             DefiniteArrayInitializer(sub_array_initializer);
  925.         else
  926.         {
  927.             AstExpression *init = (AstExpression *) array_initializer -> VariableInitializer(i);
  928.             DefiniteAssignmentSet *after_init = DefiniteExpression(init, *definitely_assigned_variables);
  929.             if (after_init)
  930.             {
  931.                 *definitely_assigned_variables = after_init -> true_set * after_init -> false_set;
  932.                 delete after_init;
  933.             }
  934.         }
  935.     }
  936.  
  937.     return;
  938. }
  939.  
  940.  
  941. inline void Semantic::DefiniteVariableInitializer(AstVariableDeclarator *variable_declarator)
  942. {
  943.     AstArrayInitializer *array_initializer = variable_declarator -> variable_initializer_opt -> ArrayInitializerCast();
  944.     if (array_initializer)
  945.         DefiniteArrayInitializer(array_initializer);
  946.     else
  947.     {
  948.         AstExpression *init = (AstExpression *) variable_declarator -> variable_initializer_opt;
  949.         DefiniteAssignmentSet *after_init = DefiniteExpression(init, *definitely_assigned_variables);
  950.         if (after_init)
  951.         {
  952.             *definitely_assigned_variables = after_init -> true_set * after_init -> false_set;
  953.             delete after_init;
  954.         }
  955.     }
  956.  
  957.     return;
  958. }
  959.  
  960.  
  961. inline void Semantic::DefiniteBlockStatements(AstBlock *block_body)
  962. {
  963.     for (int i = 0; i < block_body -> NumStatements(); i++)
  964.     {
  965.         AstStatement *statement = (AstStatement *) block_body -> Statement(i);
  966.         if (statement -> is_reachable)
  967.              DefiniteStatement(statement);
  968.         else break;
  969.     }
  970.  
  971.     return;
  972. }
  973.  
  974.  
  975. void Semantic::DefiniteBlock(Ast *stmt)
  976. {
  977.     AstBlock *block_body = (AstBlock *) stmt;
  978.  
  979.     definite_block_stack -> Push(block_body);
  980.  
  981.     for (int i = 0; i < block_body -> block_symbol -> NumVariableSymbols(); i++)
  982.     {
  983.         VariableSymbol *variable = block_body -> block_symbol -> VariableSym(i);
  984.  
  985.         definitely_assigned_variables -> RemoveElement(variable -> LocalVariableIndex());
  986.         definite_visible_variables -> AddElement(variable);
  987.     }
  988.  
  989.     DefiniteBlockStatements(block_body);
  990.  
  991.     for (int k = 0; k < block_body -> block_symbol -> NumVariableSymbols(); k++)
  992.         definite_visible_variables -> RemoveElement(block_body -> block_symbol -> VariableSym(k));
  993.  
  994.     //
  995.     // Note that in constructing the Ast, the parser encloses each
  996.     // labeled statement in its own block... Therefore, only blocks
  997.     // are labeled.
  998.     //
  999.     if (block_body -> NumLabels() > 0)
  1000.         *definitely_assigned_variables *= definite_block_stack -> TopBreakSet();
  1001.  
  1002.     definite_block_stack -> Pop();
  1003.  
  1004.     return;
  1005. }
  1006.  
  1007.  
  1008. void Semantic::DefiniteLocalVariableDeclarationStatement(Ast *stmt)
  1009. {
  1010.     AstLocalVariableDeclarationStatement *local_decl = (AstLocalVariableDeclarationStatement *) stmt;
  1011.  
  1012.     for (int i = 0; i < local_decl -> NumVariableDeclarators(); i++)
  1013.     {
  1014.         AstVariableDeclarator *variable_declarator = local_decl -> VariableDeclarator(i);
  1015.         VariableSymbol *variable_symbol = variable_declarator -> symbol;
  1016.         if (variable_symbol)
  1017.         {
  1018.             if (variable_declarator -> variable_initializer_opt)
  1019.             {
  1020.                 DefiniteVariableInitializer(variable_declarator);
  1021.                 definitely_assigned_variables -> AddElement(variable_symbol -> LocalVariableIndex());
  1022.                 if (variable_symbol -> ACC_FINAL())
  1023.                     possibly_assigned_finals -> AddElement(variable_symbol -> LocalVariableIndex());
  1024.             }
  1025.             else definitely_assigned_variables -> RemoveElement(variable_symbol -> LocalVariableIndex());
  1026.         }
  1027.     }
  1028.  
  1029.     return;
  1030. }
  1031.  
  1032.  
  1033. void Semantic::DefiniteExpressionStatement(Ast *stmt)
  1034. {
  1035.     AstExpressionStatement *expression_statement = (AstExpressionStatement *) stmt;
  1036.  
  1037.     DefiniteAssignmentSet *after_expr = DefiniteExpression(expression_statement -> expression, *definitely_assigned_variables);
  1038.     if (after_expr)
  1039.     {
  1040.         *definitely_assigned_variables = after_expr -> true_set * after_expr -> false_set;
  1041.         delete after_expr;
  1042.     }
  1043.  
  1044.    return;
  1045. }
  1046.  
  1047.  
  1048. void Semantic::DefiniteSynchronizedStatement(Ast *stmt)
  1049. {
  1050.     AstSynchronizedStatement *synchronized_statement = (AstSynchronizedStatement *) stmt;
  1051.  
  1052.     DefiniteAssignmentSet *after_expr = DefiniteExpression(synchronized_statement -> expression, *definitely_assigned_variables);
  1053.     if (after_expr)
  1054.     {
  1055.         *definitely_assigned_variables = after_expr -> true_set * after_expr -> false_set;
  1056.         delete after_expr;
  1057.     }
  1058.  
  1059.     DefiniteBlock(synchronized_statement -> block);
  1060.  
  1061.     return;
  1062. }
  1063.  
  1064.  
  1065. void Semantic::DefiniteIfStatement(Ast *stmt)
  1066. {
  1067.     AstIfStatement *if_statement = (AstIfStatement *) stmt;
  1068.  
  1069.     DefiniteAssignmentSet *after_expr = DefiniteExpression(if_statement -> expression, *definitely_assigned_variables);
  1070.     BitSet after_expr_finals(*possibly_assigned_finals);
  1071.     BitSet *starting_set = (after_expr ? (BitSet *) NULL : new BitSet(*definitely_assigned_variables));
  1072.     if (after_expr)
  1073.          *definitely_assigned_variables = after_expr -> true_set;
  1074.  
  1075.     //
  1076.     // If the expression in the if-statement is a boolean constant expression then get its value.
  1077.     //
  1078.     IntLiteralValue *if_constant_expr = (if_statement -> expression -> Type() == control.boolean_type &&
  1079.                                          if_statement -> expression -> IsConstant()
  1080.                                                                      ? (IntLiteralValue *) if_statement -> expression -> value
  1081.                                                                      : (IntLiteralValue *) NULL);
  1082.     //
  1083.     // If either the expression is not constant or its value is true, then
  1084.     // check the statement that make up the true part of the if statement
  1085.     //
  1086.     if ((! if_constant_expr) || if_constant_expr -> value)
  1087.         DefiniteBlock(if_statement -> true_statement);
  1088.  
  1089.     //
  1090.     // Recall that the parser ensures that the statements that appear in an if-statement
  1091.     // (both the true and false statement) are enclosed in a block.
  1092.     //
  1093.     if (! if_statement -> false_statement_opt) // no else part ?
  1094.     {
  1095.         *definitely_assigned_variables *= (after_expr ? after_expr -> false_set : *starting_set);
  1096.         *possibly_assigned_finals += after_expr_finals;
  1097.     }
  1098.     else
  1099.     {
  1100.         BitSet after_true_finals(*possibly_assigned_finals);
  1101.         *possibly_assigned_finals = after_expr_finals;
  1102.  
  1103.         BitSet true_set(*definitely_assigned_variables);
  1104.         *definitely_assigned_variables = (after_expr ? after_expr -> false_set : *starting_set);
  1105.  
  1106.         if ((! if_constant_expr) || (! if_constant_expr -> value)) // either the expression is not constant or its value is false?
  1107.             DefiniteBlock(if_statement -> false_statement_opt);
  1108.  
  1109.         *definitely_assigned_variables *= true_set;
  1110.         *possibly_assigned_finals += after_true_finals;
  1111.     }
  1112.  
  1113.     delete after_expr;   // nothing happens if after_expr is NULL
  1114.     delete starting_set; // nothing happens if starting_set is NULL
  1115.  
  1116.     return;
  1117. }
  1118.  
  1119.  
  1120. void Semantic::DefiniteLoopBody(AstStatement *statement)
  1121. {
  1122.     definite_final_assignment_stack -> Push();
  1123.  
  1124.     BitSet starting_set(*possibly_assigned_finals);
  1125.  
  1126.     DefiniteStatement(statement);
  1127.  
  1128.     BitSet exit_set(*possibly_assigned_finals);
  1129.     exit_set += definite_block_stack -> TopFinalContinueSet();
  1130.  
  1131.     //
  1132.     // The set of variables that may have been possibly assigned within the body of a loop
  1133.     // consists of the set of variables that was possibly assigned at the end of the block
  1134.     // UNION the set of variables that was possibly assigned prior to a continue statement
  1135.     // within the body of the loop MINUS the set of variables that were possibly assigned
  1136.     // prior to entering the loop.
  1137.     //
  1138.     BitSet new_set(exit_set);
  1139.     new_set -= starting_set;
  1140.  
  1141.     for (int k = 0; k < definite_final_assignment_stack -> Top().Length(); k++)
  1142.     {
  1143.         AstExpression *name = definite_final_assignment_stack -> Top()[k];
  1144.         VariableSymbol *variable = (VariableSymbol *) name -> symbol;
  1145.  
  1146.         if (definite_visible_variables -> IsElement(variable) && new_set[variable -> LocalVariableIndex()])
  1147.         {
  1148.             ReportSemError(SemanticError::FINAL_VARIABLE_TARGET_IN_LOOP,
  1149.                            name -> LeftToken(),
  1150.                            name -> RightToken(),
  1151.                            variable -> Name());
  1152.         }
  1153.     }
  1154.  
  1155.     exit_set += definite_block_stack -> TopFinalBreakSet();
  1156.     *possibly_assigned_finals = exit_set;
  1157.     definite_final_assignment_stack -> Pop();
  1158.  
  1159.     return;
  1160. }
  1161.  
  1162.  
  1163. void Semantic::DefiniteWhileStatement(Ast *stmt)
  1164. {
  1165.     AstWhileStatement *while_statement = (AstWhileStatement *) stmt;
  1166.  
  1167.     BreakableStatementStack().Push(definite_block_stack -> TopBlock());
  1168.     ContinuableStatementStack().Push(stmt);
  1169.  
  1170.     DefiniteAssignmentSet *after_expr = DefiniteExpression(while_statement -> expression, *definitely_assigned_variables);
  1171.  
  1172.     bool while_expr = true;
  1173.     if (while_statement -> expression -> Type() == control.boolean_type && while_statement -> expression -> IsConstant())
  1174.     {
  1175.         IntLiteralValue *literal = (IntLiteralValue *) while_statement -> expression -> value;
  1176.         if (! literal -> value)
  1177.             while_expr = false;
  1178.     }
  1179.  
  1180.     if (after_expr)
  1181.     {
  1182.         *definitely_assigned_variables = after_expr -> true_set;
  1183.         //
  1184.         // If the expression is always false, the body of the loop is not reachable and therefore will never execute.
  1185.         //
  1186.         if (while_expr)
  1187.             DefiniteLoopBody(while_statement -> statement);
  1188.         *definitely_assigned_variables = (after_expr -> false_set * definite_block_stack -> TopBreakSet());
  1189.         delete after_expr;
  1190.     }
  1191.     else
  1192.     {
  1193.         BitSet starting_set(*definitely_assigned_variables);
  1194.         //
  1195.         // If the expression is always false, the body of the loop is not reachable and therefore will never execute.
  1196.         //
  1197.         if (while_expr)
  1198.             DefiniteLoopBody(while_statement -> statement);
  1199.         *definitely_assigned_variables = (starting_set * definite_block_stack -> TopBreakSet());
  1200.     }
  1201.  
  1202.     ContinuableStatementStack().Pop();
  1203.     BreakableStatementStack().Pop();
  1204.  
  1205.     return;
  1206. }
  1207.  
  1208.  
  1209. void Semantic::DefiniteForStatement(Ast *stmt)
  1210. {
  1211.     AstForStatement *for_statement = (AstForStatement *) stmt;
  1212.  
  1213.     //
  1214.     // Note that in constructing the Ast, the parser encloses each
  1215.     // for-statement whose for-init-statements starts with a local
  1216.     // variable declaration in its own block. Therefore a redeclaration
  1217.     // of another local variable with the same name in a different loop
  1218.     // at the same nesting level will not cause any conflict.
  1219.     //
  1220.     // For example, the following sequence of statements is legal:
  1221.     //
  1222.     //     for (int i = 0; i < 10; i++);
  1223.     //     for (int i = 10; i < 20; i++);
  1224.     //
  1225.     for (int i = 0; i < for_statement -> NumForInitStatements(); i++)
  1226.         DefiniteStatement(for_statement -> ForInitStatement(i));
  1227.  
  1228.     BreakableStatementStack().Push(definite_block_stack -> TopBlock());
  1229.     ContinuableStatementStack().Push(stmt);
  1230.  
  1231.     DefiniteAssignmentSet *after_end_expression = NULL;
  1232.     BitSet before_statement(universe -> Size());
  1233.  
  1234.     bool for_expr = true;
  1235.     if (for_statement -> end_expression_opt)
  1236.     {
  1237.         after_end_expression = DefiniteExpression(for_statement -> end_expression_opt, *definitely_assigned_variables);
  1238.  
  1239.         if (for_statement -> end_expression_opt -> Type() == control.boolean_type &&
  1240.             for_statement -> end_expression_opt -> IsConstant())
  1241.         {
  1242.             IntLiteralValue *literal = (IntLiteralValue *) for_statement -> end_expression_opt -> value;
  1243.             if (! literal -> value)
  1244.                 for_expr = false;
  1245.         }
  1246.     }
  1247.  
  1248.     if (after_end_expression)
  1249.          *definitely_assigned_variables = after_end_expression -> true_set;
  1250.     else before_statement = *definitely_assigned_variables;
  1251.  
  1252.     //
  1253.     // If the expression is always false, the body of the loop is not reachable and therefore will never execute.
  1254.     //
  1255.     if (for_expr)
  1256.         DefiniteLoopBody(for_statement -> statement);
  1257.  
  1258.     //
  1259.     // Compute the set of variables that are definitely assigned after the
  1260.     // contained statement and after every continue statement that may exit
  1261.     // the body of the for statement.
  1262.     //
  1263.     *definitely_assigned_variables *= definite_block_stack -> TopContinueSet();
  1264.     for (int j = 0; j < for_statement -> NumForUpdateStatements(); j++)
  1265.         DefiniteExpressionStatement(for_statement -> ForUpdateStatement(j));
  1266.  
  1267.     //
  1268.     // Compute the set of variables that belongs to both sets below:
  1269.     //
  1270.     //    . the universe if no condition expression is present;
  1271.     //      otherwise, the set of variables that is definitely assigned when
  1272.     //      the condition expression is false.
  1273.     //
  1274.     //    . the set of variables that is definitely assigned before every
  1275.     //      break statement that may exit the for statement.
  1276.     //
  1277.     *definitely_assigned_variables = (for_statement -> end_expression_opt
  1278.                                                      ? (after_end_expression ? after_end_expression -> false_set : before_statement)
  1279.                                                      : *universe); // set of variables that depend on the condition
  1280.  
  1281.     //
  1282.     // The replacement
  1283.     //
  1284.     *definitely_assigned_variables *= definite_block_stack -> TopBreakSet();
  1285.  
  1286.     delete after_end_expression; // nothing happens if after_end_expression is NULL
  1287.  
  1288.     ContinuableStatementStack().Pop();
  1289.     BreakableStatementStack().Pop();
  1290.  
  1291.     return;
  1292. }
  1293.  
  1294.  
  1295. void Semantic::DefiniteDoStatement(Ast *stmt)
  1296. {
  1297.     AstDoStatement *do_statement = (AstDoStatement *) stmt;
  1298.  
  1299.     BreakableStatementStack().Push(definite_block_stack -> TopBlock());
  1300.     ContinuableStatementStack().Push(stmt);
  1301.  
  1302.     bool do_expr = true;
  1303.     if (do_statement -> expression -> Type() == control.boolean_type && do_statement -> expression -> IsConstant())
  1304.     {
  1305.         IntLiteralValue *literal = (IntLiteralValue *) do_statement -> expression -> value;
  1306.         if (! literal -> value)
  1307.             do_expr = false;
  1308.     }
  1309.  
  1310.     if (do_expr)
  1311.          DefiniteLoopBody(do_statement -> statement);
  1312.     else DefiniteStatement(do_statement -> statement); // The expression is always false therefore, loop will execute exactly once.
  1313.  
  1314.     BitSet after_stmt(*definitely_assigned_variables);
  1315.     *definitely_assigned_variables *= definite_block_stack -> TopContinueSet();
  1316.     DefiniteAssignmentSet *after_expr = DefiniteExpression(do_statement -> expression, *definitely_assigned_variables);
  1317.     if (after_expr)
  1318.     {
  1319.         *definitely_assigned_variables = (after_expr -> false_set * definite_block_stack -> TopBreakSet());
  1320.         delete after_expr;
  1321.     }
  1322.     else *definitely_assigned_variables *= definite_block_stack -> TopBreakSet();
  1323.  
  1324.     ContinuableStatementStack().Pop();
  1325.     BreakableStatementStack().Pop();
  1326.  
  1327.     return;
  1328. }
  1329.  
  1330.  
  1331. void Semantic::DefiniteSwitchStatement(Ast *stmt)
  1332. {
  1333.     AstSwitchStatement *switch_statement = (AstSwitchStatement *) stmt;
  1334.  
  1335.     AstBlock *block_body = switch_statement -> switch_block;
  1336.     definite_block_stack -> Push(block_body);
  1337.     BreakableStatementStack().Push(block_body);
  1338.  
  1339.     DefiniteAssignmentSet *after_expr = DefiniteExpression(switch_statement -> expression, *definitely_assigned_variables);
  1340.     if (after_expr)
  1341.     {
  1342.         *definitely_assigned_variables = after_expr -> true_set * after_expr -> false_set;
  1343.         delete after_expr;
  1344.     }
  1345.  
  1346.     BitSet starting_set(*definitely_assigned_variables),
  1347.            after_expr_finals(*possibly_assigned_finals),
  1348.            switch_finals_union(*possibly_assigned_finals);
  1349.  
  1350.     for (int i = 0; i < block_body -> NumStatements(); i++)
  1351.     {
  1352.         AstSwitchBlockStatement *switch_block_statement = (AstSwitchBlockStatement *) block_body -> Statement(i);
  1353.  
  1354.         *definitely_assigned_variables = starting_set;
  1355.         *possibly_assigned_finals = after_expr_finals;
  1356.  
  1357.         for (int k = 0; k < switch_block_statement -> NumStatements(); k++)
  1358.         {
  1359.             AstStatement *statement = (AstStatement *) switch_block_statement -> Statement(k);
  1360.             if (statement -> is_reachable)
  1361.                  DefiniteStatement(statement);
  1362.             else break;
  1363.         }
  1364.  
  1365.         //
  1366.         // Update possibly_assigned_finals here. If a continue, break (of an enclosing statement), return or throw
  1367.         // statement was encountered...
  1368.         //
  1369.         switch_finals_union += definite_block_stack -> TopFinalExitSet(*possibly_assigned_finals);
  1370.     }
  1371.  
  1372.     if (switch_statement -> default_case.switch_block_statement) // Is there a default case?
  1373.          *definitely_assigned_variables *= definite_block_stack -> TopBreakSet();
  1374.     else *definitely_assigned_variables = starting_set;
  1375.  
  1376.     *possibly_assigned_finals = switch_finals_union;
  1377.  
  1378.     BreakableStatementStack().Pop();
  1379.     definite_block_stack -> Pop();
  1380.  
  1381.     return;
  1382. }
  1383.  
  1384.  
  1385. void Semantic::DefiniteBreakStatement(Ast *stmt)
  1386. {
  1387.     AstBreakStatement *break_statement = (AstBreakStatement *) stmt;
  1388.  
  1389.     //
  1390.     // Compute the set of variables that are definitely assigned prior to executing the break.
  1391.     //
  1392.     definite_block_stack -> BreakSet(break_statement -> nesting_level) *= (*definitely_assigned_variables);
  1393.     definite_block_stack -> FinalBreakSet(break_statement -> nesting_level) += (*possibly_assigned_finals);
  1394.  
  1395.     //
  1396.     // After execution of a break statement, it is vacuously true
  1397.     // that every variable has definitely been assigned and no final
  1398.     // variable has been possibly assigned (as nothing is reachable
  1399.     // any way).
  1400.     //
  1401.     *definitely_assigned_variables = *universe;
  1402.     possibly_assigned_finals -> SetEmpty();
  1403.  
  1404.     return;
  1405. }
  1406.  
  1407.  
  1408. void Semantic::DefiniteContinueStatement(Ast *stmt)
  1409. {
  1410.     AstContinueStatement *continue_statement = (AstContinueStatement *) stmt;
  1411.  
  1412.     //
  1413.     // Compute the set of variables that are definitely assigned prior to executing the continue.
  1414.     //
  1415.     definite_block_stack -> ContinueSet(continue_statement -> nesting_level) *= (*definitely_assigned_variables);
  1416.     definite_block_stack -> FinalContinueSet(continue_statement -> nesting_level) += (*possibly_assigned_finals);
  1417.  
  1418.     //
  1419.     // After execution of a continue statement, it is vacuously true
  1420.     // that every variable has definitely been assigned and no final
  1421.     // variable has been possibly assigned (as nothing is reachable
  1422.     // any way).
  1423.     //
  1424.     *definitely_assigned_variables = *universe;
  1425.     possibly_assigned_finals -> SetEmpty();
  1426.  
  1427.     return;
  1428. }
  1429.  
  1430.  
  1431. void Semantic::DefiniteReturnStatement(Ast *stmt)
  1432. {
  1433.     AstReturnStatement *return_statement = (AstReturnStatement *) stmt;
  1434.  
  1435.     if (return_statement -> expression_opt)
  1436.     {
  1437.         DefiniteAssignmentSet *after_expr = DefiniteExpression(return_statement -> expression_opt, *definitely_assigned_variables);
  1438.         if (after_expr)
  1439.             delete after_expr;
  1440.     }
  1441.  
  1442.     //
  1443.     // Compute the set of variables that are definitely assigned prior to executing
  1444.     // this return statement. Note that this set is only relevant to the method or
  1445.     // constructor block containing this statement.
  1446.     //
  1447.     // TODO: Do we really need this?
  1448.     //
  1449.     //    definite_block_stack -> TopReturnSet() *= (*definitely_assigned_variables);
  1450.     //
  1451.  
  1452.     //
  1453.     // Compute the set of variables that are possibly assigned prior to executing this return statement.
  1454.     // We have a few cases to consider:
  1455.     //
  1456.     //    1. The return statement is not contained in a try statement - the possibly-assigned set is only relevant
  1457.     //       to the enclosing method (or constructor) block. The definitely assigned set is updated as if the return
  1458.     //       statement was a break statement out of the method (or constructor) block.
  1459.     //
  1460.     //    2. If the return statement is contained in a try main block or a try
  1461.     //       catch block that contains a finally clause - the possibly-assigned
  1462.     //       block is relevant to that main try block or catch block.
  1463.     //
  1464.     //    3. otherwise, treat the return statement as if it immediately followed its containing try statement
  1465.     //
  1466.     if (definite_try_stack -> Size() == 0)
  1467.         definite_block_stack -> ReturnSet(0) *= (*definitely_assigned_variables);
  1468.     else
  1469.     {
  1470.         for (int i = definite_try_stack -> Size() - 1; i >= 0; i--)
  1471.         {
  1472.             AstTryStatement *try_statement = definite_try_stack -> TryStatement(i);
  1473.             //
  1474.             // Is the return statement enclosed in a try main block or catch block
  1475.             // that  contains a finally clause. Note that a try statement is removed from
  1476.             // the definite_try_stack before its finally clause is processed. thus, a return
  1477.             // statement that is enclosed in a finally clause will appear in an enclosing
  1478.             // try statement, if any...
  1479.             //
  1480.             if (try_statement -> finally_clause_opt)
  1481.             {
  1482.                 int k;
  1483.                 for (k = definite_block_stack -> Size() - 1;
  1484.                      definite_block_stack -> Block(k) != definite_try_stack -> Block(i);
  1485.                      k--)
  1486.                     ;
  1487.  
  1488.                 assert(k >= 0);
  1489.  
  1490.                 definite_block_stack -> FinalReturnSet(k) += (*possibly_assigned_finals);
  1491.                 break;
  1492.             }
  1493.         }
  1494.     }
  1495.  
  1496.     //
  1497.     // After execution of a return statement, it is vacuously true
  1498.     // that every variable has definitely been assigned and no final
  1499.     // variable has been possibly assigned (as nothing is reachable
  1500.     // any way).
  1501.     //
  1502.     *definitely_assigned_variables = *universe;
  1503.     possibly_assigned_finals -> SetEmpty();
  1504.  
  1505.     return;
  1506. }
  1507.  
  1508.  
  1509. void Semantic::DefiniteThrowStatement(Ast *stmt)
  1510. {
  1511.     AstThrowStatement *throw_statement = (AstThrowStatement *) stmt;
  1512.  
  1513.     DefiniteAssignmentSet *after_expr = DefiniteExpression(throw_statement -> expression, *definitely_assigned_variables);
  1514.     if (after_expr)
  1515.         delete after_expr;
  1516.  
  1517.     //
  1518.     // Compute the set of variables that are definitely assigned prior to executing
  1519.     // this throw statement. Note that this set is only relevant to the method or
  1520.     // constructor block containing this statement.
  1521.     //
  1522.     // TODO: Do we really need this?
  1523.     //
  1524.     //    definite_block_stack -> TopThrowSet() *= (*definitely_assigned_variables);
  1525.     //
  1526.  
  1527.     //
  1528.     // Compute the set of variables that are possibly assigned prior to executing this throw statement
  1529.     // and update the proper enclosing block appropriately.
  1530.     //
  1531.     // We have a few cases to consider:
  1532.     //
  1533.     //    1. The throw statement is not contained in a try statement - the possibly-assigned
  1534.     //       set is only relevant to the enclosing method (or constructor) block. If the
  1535.     //       containing function in question is a method (i.e., not a constructor) then the
  1536.     //       definitely assigned set is updated as if the throw statement was a break statement
  1537.     //       out of the method block.
  1538.     //
  1539.     //    2. The throw statement is enclosed in a try statement main block or catch clause.
  1540.     //
  1541.     //        2a. if the nearest try-block that encloses the throw statement is a main try-block -
  1542.     //            the possibly-assigned block is relevant to that main block.
  1543.     //
  1544.     //        2b. if the nearest try-block that encloses the throw statement is a catch-block and
  1545.     //            the try block contains a finally clause - the possibly-assigned block is relevant
  1546.     //            to the catch-block
  1547.     //
  1548.     //        2c. otherwise, treat the throw statement as if it immediately followed its containing
  1549.     //            try statement
  1550.     //
  1551.     if (definite_try_stack -> Size() == 0)
  1552.     {
  1553.         if (ThisMethod() -> Identity() != control.init_name_symbol) // Not a constructor
  1554.             definite_block_stack -> ThrowSet(0) *= (*definitely_assigned_variables);
  1555.     }
  1556.     else
  1557.     {
  1558.         for (int i = definite_try_stack -> Size() - 1; i >= 0; i--)
  1559.         {
  1560.             AstTryStatement *try_statement = definite_try_stack -> TryStatement(i);
  1561.             //
  1562.             // Is the return statement enclosed in a try main block or catch block
  1563.             // that  contains a finally clause. Note that a try statement is removed from
  1564.             // the definite_try_stack before its finally clause is processed. thus, a return
  1565.             // statement that is enclosed in a finally clause will appear in an enclosing
  1566.             // try statement, if any...
  1567.             //
  1568.             if (try_statement -> block == definite_try_stack -> Block(i)) // Is the throw statement enclosed in main try block?
  1569.             {
  1570.                 int k;
  1571.                 for (k = definite_block_stack -> Size() - 1; definite_block_stack -> Block(k) != try_statement -> block; k--)
  1572.                     ;
  1573.  
  1574.                 assert(k >= 0);
  1575.  
  1576.                 definite_block_stack -> FinalThrowSet(k) += (*possibly_assigned_finals);
  1577.                 break;
  1578.             }
  1579.             else if (try_statement -> finally_clause_opt)
  1580.             {
  1581.                 int k;
  1582.                 for (k = definite_block_stack -> Size() - 1;
  1583.                      definite_block_stack -> Block(k) != definite_try_stack -> Block(i);
  1584.                      k--)
  1585.                     ;
  1586.  
  1587.                 assert(k >= 0);
  1588.  
  1589.                 definite_block_stack -> FinalThrowSet(k) += (*possibly_assigned_finals);
  1590.                 break;
  1591.             }
  1592.         }
  1593.     }
  1594.  
  1595.     //
  1596.     // After execution of a throw statement, it is vacuously true
  1597.     // that every variable has definitely been assigned and no final
  1598.     // variable has been possibly assigned (as nothing is reachable
  1599.     // any way).
  1600.     //
  1601.     *definitely_assigned_variables = *universe;
  1602.     possibly_assigned_finals -> SetEmpty();
  1603.  
  1604.     return;
  1605. }
  1606.  
  1607.  
  1608. void Semantic::DefiniteTryStatement(Ast *stmt)
  1609. {
  1610.     AstTryStatement *try_statement = (AstTryStatement *) stmt;
  1611.     definite_try_stack -> Push(try_statement);
  1612.  
  1613.     BitSet starting_set(*definitely_assigned_variables);
  1614.  
  1615.     AstBlock *try_block_body = try_statement -> block;
  1616.     definite_block_stack -> Push(try_block_body);
  1617.     definite_try_stack -> SetTopBlock(try_block_body);
  1618.  
  1619.     for (int j = 0; j < try_block_body -> block_symbol -> NumVariableSymbols(); j++)
  1620.     {
  1621.         VariableSymbol *variable = try_block_body -> block_symbol -> VariableSym(j);
  1622.  
  1623.         definitely_assigned_variables -> RemoveElement(variable -> LocalVariableIndex());
  1624.         definite_visible_variables -> AddElement(variable);
  1625.     }
  1626.  
  1627.     BitSet before_try_finals(*possibly_assigned_finals);
  1628.  
  1629.     DefiniteBlockStatements(try_block_body);
  1630.  
  1631.     BitSet &exit_set = definite_block_stack -> TopFinalExitSet(*possibly_assigned_finals),
  1632.            before_catch_finals(exit_set),
  1633.            possibly_finals_union(exit_set);
  1634.  
  1635.     //
  1636.     // Once we are done with a block, its enclosed local variables are no longer visible.
  1637.     //
  1638.     for (int l = 0; l < try_block_body -> block_symbol -> NumVariableSymbols(); l++)
  1639.         definite_visible_variables -> RemoveElement(try_block_body -> block_symbol -> VariableSym(l));
  1640.  
  1641.     definite_block_stack -> Pop();
  1642.  
  1643.     //
  1644.     // We initilize the variable after_blocks here. It is used to calculate intersection
  1645.     // of the set of variables that are definitely assigned by all the blocks: the try block,
  1646.     // all the catch blocks, if any, and the finally block, if there is one.
  1647.     //
  1648.     BitSet after_blocks(*definitely_assigned_variables);
  1649.  
  1650.     //
  1651.     // Recall that the body of the catch blocks must not be
  1652.     // processed within the environment of the associated try whose
  1653.     // exceptions they are supposed to catch but within the immediate
  1654.     // enclosing block (which may itself be a try block).
  1655.     //
  1656.     for (int i = 0; i < try_statement -> NumCatchClauses(); i++)
  1657.     {
  1658.         *definitely_assigned_variables = starting_set;
  1659.  
  1660.         //
  1661.         // We process the catch block here instead of invoking DefiniteBlock,
  1662.         // in order to make sure that the formal parameter (which is declared)
  1663.         // inside the block is identified as having been definitely assigned.
  1664.         //
  1665.         AstCatchClause *clause = try_statement -> CatchClause(i);
  1666.  
  1667.         AstBlock *clause_block_body = clause -> block;
  1668.         definite_block_stack -> Push(clause_block_body);
  1669.         definite_try_stack -> SetTopBlock(clause_block_body);
  1670.  
  1671.         for (int j = 0; j < clause_block_body -> block_symbol -> NumVariableSymbols(); j++)
  1672.         {
  1673.             VariableSymbol *variable = clause_block_body -> block_symbol -> VariableSym(j);
  1674.  
  1675.             definitely_assigned_variables -> RemoveElement(variable -> LocalVariableIndex());
  1676.             definite_visible_variables -> AddElement(variable);
  1677.         }
  1678.  
  1679.         //
  1680.         // The parameter must be (re) added after removing all variables in the block
  1681.         // from the set !!!
  1682.         //
  1683.         definitely_assigned_variables -> AddElement(clause -> parameter_symbol -> LocalVariableIndex());
  1684.         *possibly_assigned_finals = before_catch_finals;
  1685.         if (clause -> parameter_symbol -> ACC_FINAL())
  1686.             possibly_assigned_finals -> AddElement(clause -> parameter_symbol -> LocalVariableIndex());
  1687.  
  1688.         DefiniteBlockStatements(clause_block_body);
  1689.  
  1690.         //
  1691.         // Once we are done with a block, its enclosed local variables are no longer visible.
  1692.         //
  1693.         for (int k = 0; k < clause_block_body -> block_symbol -> NumVariableSymbols(); k++)
  1694.             definite_visible_variables -> RemoveElement(clause_block_body -> block_symbol -> VariableSym(k));
  1695.  
  1696.         possibly_finals_union += definite_block_stack -> TopFinalExitSet(*possibly_assigned_finals);
  1697.  
  1698.         definite_block_stack -> Pop();
  1699.  
  1700.         //
  1701.         // Process the set of variables that were definitely assigned
  1702.         // after this catch block
  1703.         //
  1704.         after_blocks *= *definitely_assigned_variables;
  1705.     }
  1706.  
  1707.     *possibly_assigned_finals = possibly_finals_union;
  1708.     definite_try_stack -> Pop();
  1709.  
  1710.     //
  1711.     // Like the catch clauses, a finally block must not be processed
  1712.     // in the environment of its associated try block but in the
  1713.     // environment of its immediate enclosing block.
  1714.     //
  1715.     if (try_statement -> finally_clause_opt)
  1716.     {
  1717.         *definitely_assigned_variables = starting_set;
  1718.  
  1719.         DefiniteBlock(try_statement -> finally_clause_opt -> block);
  1720.  
  1721.         *definitely_assigned_variables += after_blocks;
  1722.     }
  1723.     else *definitely_assigned_variables = after_blocks;
  1724.  
  1725.     return;
  1726. }
  1727.  
  1728.  
  1729. void Semantic::DefiniteEmptyStatement(Ast *stmt)
  1730. {
  1731.     return;
  1732. }
  1733.  
  1734.  
  1735. void Semantic::DefiniteClassDeclaration(Ast *decl)
  1736. {
  1737.     //
  1738.     // All the methods within the body of a local class are processed when
  1739.     // the class is compiled.
  1740.     //
  1741.  
  1742.     return;
  1743. }
  1744.  
  1745.  
  1746. void Semantic::DefiniteMethodBody(AstMethodDeclaration *method_declaration, Tuple<VariableSymbol *> &finals)
  1747. {
  1748.     if (! method_declaration -> method_body -> EmptyStatementCast())
  1749.     {
  1750.         AstConstructorBlock *constructor_block = method_declaration -> method_body -> ConstructorBlockCast();
  1751.         AstBlock *block_body = (constructor_block ? constructor_block -> block : (AstBlock *) method_declaration -> method_body);
  1752.  
  1753.         universe = new BitSet(block_body -> block_symbol -> max_variable_index + finals.Length(), BitSet::UNIVERSE);
  1754.         definite_block_stack = new DefiniteBlockStack(method_declaration -> method_symbol -> max_block_depth, universe -> Size());
  1755.         definite_try_stack = new DefiniteTryStack(method_declaration -> method_symbol -> max_block_depth);
  1756.         definite_final_assignment_stack =  new DefiniteFinalAssignmentStack();
  1757.         definite_visible_variables = new SymbolSet(universe -> Size());
  1758.         definitely_assigned_variables = new BitSet(universe -> Size(), BitSet::EMPTY);
  1759.         possibly_assigned_finals = new BitSet(universe -> Size(), BitSet::EMPTY);
  1760.         for (int i = 0; i < finals.Length(); i++) // Assume that all final instance variables have been assigned a value.
  1761.         {
  1762.             int index = block_body -> block_symbol -> max_variable_index + i;
  1763.             finals[i] -> SetLocalVariableIndex(index);
  1764.             definitely_assigned_variables -> AddElement(index);
  1765.             possibly_assigned_finals -> AddElement(index);
  1766.             definite_visible_variables -> AddElement(finals[i]);
  1767.         }
  1768.  
  1769.         definite_block_stack -> Push(block_body);
  1770.  
  1771.         AstMethodDeclarator *method_declarator = method_declaration -> method_declarator;
  1772.         for (int k = 0; k < method_declarator -> NumFormalParameters(); k++)
  1773.         {
  1774.             AstVariableDeclarator *formal_declarator = method_declarator -> FormalParameter(k) -> formal_declarator;
  1775.             definitely_assigned_variables -> AddElement(formal_declarator -> symbol -> LocalVariableIndex());
  1776.             if (formal_declarator -> symbol -> ACC_FINAL())
  1777.                 possibly_assigned_finals -> AddElement(formal_declarator -> symbol -> LocalVariableIndex());
  1778.             definite_visible_variables -> AddElement(formal_declarator -> symbol);
  1779.         }
  1780.  
  1781.         for (int l = 0; l < block_body -> block_symbol -> NumVariableSymbols(); l++)
  1782.             definite_visible_variables -> AddElement(block_body -> block_symbol -> VariableSym(l));
  1783.  
  1784.         DefiniteBlockStatements(block_body);
  1785.  
  1786.         definite_block_stack -> Pop();
  1787.  
  1788.         delete universe;
  1789.         delete definitely_assigned_variables;
  1790.         delete definite_block_stack;
  1791.         delete definite_try_stack;
  1792.         delete definite_final_assignment_stack;
  1793.         delete definite_visible_variables;
  1794.         delete possibly_assigned_finals;
  1795.     }
  1796.  
  1797.     return;
  1798. }
  1799.  
  1800.  
  1801. void Semantic::DefiniteConstructorBody(AstConstructorDeclaration *constructor_declaration, Tuple<VariableSymbol *> &finals)
  1802. {
  1803.     AstConstructorBlock *constructor_block = constructor_declaration -> constructor_body;
  1804.     AstBlock *block_body = constructor_block -> block;
  1805.  
  1806.     universe = new BitSet(block_body -> block_symbol -> max_variable_index + finals.Length(), BitSet::UNIVERSE);
  1807.     definite_block_stack = new DefiniteBlockStack(constructor_declaration -> constructor_symbol -> max_block_depth,
  1808.                                                   universe -> Size());
  1809.     definite_try_stack = new DefiniteTryStack(constructor_declaration -> constructor_symbol -> max_block_depth);
  1810.     definite_final_assignment_stack =  new DefiniteFinalAssignmentStack();
  1811.     definite_visible_variables = new SymbolSet(universe -> Size());
  1812.     definitely_assigned_variables = new BitSet(universe -> Size(), BitSet::EMPTY);
  1813.     possibly_assigned_finals = new BitSet(universe -> Size(), BitSet::EMPTY);
  1814.     for (int i = 0; i < finals.Length(); i++)
  1815.     {
  1816.         int index = block_body -> block_symbol -> max_variable_index + i;
  1817.  
  1818.         finals[i] -> SetLocalVariableIndex(index);
  1819.         if (finals[i] -> IsDefinitelyAssigned())
  1820.         {
  1821.             definitely_assigned_variables -> AddElement(index);
  1822.             possibly_assigned_finals -> AddElement(index);
  1823.         }
  1824.         else if (finals[i] -> IsPossiblyAssigned())
  1825.             possibly_assigned_finals -> AddElement(index);
  1826.         definite_visible_variables -> AddElement(finals[i]);
  1827.     }
  1828.  
  1829.     //
  1830.     // As an explicit constructor call cannot refer to any locally declared variables
  1831.     // other than formal parameters, no local variable can be assigned within it (other
  1832.     // than a formal parameter which is considered to have been assigned anyway). Therefore,
  1833.     // the following code is not necessary:
  1834.     //
  1835.     //    if (this_call)
  1836.     //         DefiniteThisCall(this_call);
  1837.     //    else if (super_call)
  1838.     //         DefiniteSuperCall(super_call);
  1839.     //
  1840.  
  1841.     definite_block_stack -> Push(block_body);
  1842.  
  1843.     AstMethodDeclarator *constructor_declarator = constructor_declaration -> constructor_declarator;
  1844.     for (int j = 0; j < constructor_declarator -> NumFormalParameters(); j++)
  1845.     {
  1846.         AstVariableDeclarator *formal_declarator = constructor_declarator -> FormalParameter(j) -> formal_declarator;
  1847.         definitely_assigned_variables -> AddElement(formal_declarator -> symbol -> LocalVariableIndex());
  1848.         if (formal_declarator -> symbol -> ACC_FINAL())
  1849.             possibly_assigned_finals -> AddElement(formal_declarator -> symbol -> LocalVariableIndex());
  1850.         definite_visible_variables -> AddElement(formal_declarator -> symbol);
  1851.     }
  1852.  
  1853.     for (int l = 0; l < block_body -> block_symbol -> NumVariableSymbols(); l++)
  1854.         definite_visible_variables -> AddElement(block_body -> block_symbol -> VariableSym(l));
  1855.  
  1856.     DefiniteBlockStatements(block_body);
  1857.  
  1858.  
  1859.     //
  1860.     // Compute the set of finals that has definitely been assigned in this constructor
  1861.     //
  1862.     BitSet &exit_set = definite_block_stack -> TopExitSet(*definitely_assigned_variables);
  1863.     for (int k = 0; k < finals.Length(); k++)
  1864.     {
  1865.         int index = block_body -> block_symbol -> max_variable_index + k;
  1866.         if (exit_set[index])
  1867.             finals[k] -> MarkDefinitelyAssigned();
  1868.     }
  1869.  
  1870.     definite_block_stack -> Pop();
  1871.  
  1872.     delete universe;
  1873.     delete definitely_assigned_variables;
  1874.     delete definite_block_stack;
  1875.     delete definite_try_stack;
  1876.     delete definite_final_assignment_stack;
  1877.     delete definite_visible_variables;
  1878.     delete possibly_assigned_finals;
  1879.  
  1880.     return;
  1881. }
  1882.  
  1883.  
  1884. void Semantic::DefiniteBlockInitializer(AstBlock *block_body, int stack_size, Tuple<VariableSymbol *> &finals)
  1885. {
  1886.     universe = new BitSet(block_body -> block_symbol -> max_variable_index + finals.Length(), BitSet::UNIVERSE);
  1887.     definite_block_stack = new DefiniteBlockStack(stack_size + 1, universe -> Size()); // +1 to simulate enclosing method block
  1888.     definite_try_stack = new DefiniteTryStack(stack_size + 1);
  1889.     definite_final_assignment_stack =  new DefiniteFinalAssignmentStack();
  1890.     definite_visible_variables = new SymbolSet(universe -> Size());
  1891.     definitely_assigned_variables = new BitSet(universe -> Size(), BitSet::EMPTY);
  1892.     possibly_assigned_finals = new BitSet(universe -> Size(), BitSet::EMPTY);
  1893.     for (int i = 0; i < finals.Length(); i++)
  1894.     {
  1895.         int index = block_body -> block_symbol -> max_variable_index + i;
  1896.  
  1897.         finals[i] -> SetLocalVariableIndex(index);
  1898.         if (finals[i] -> IsDefinitelyAssigned())
  1899.         {
  1900.             definitely_assigned_variables -> AddElement(index);
  1901.             possibly_assigned_finals -> AddElement(index);
  1902.         }
  1903.         else if (finals[i] -> IsPossiblyAssigned())
  1904.             possibly_assigned_finals -> AddElement(index);
  1905.         definite_visible_variables -> AddElement(finals[i]);
  1906.     }
  1907.  
  1908.     definite_block_stack -> Push(NULL); // No method available
  1909.     definite_block_stack -> Push(block_body);
  1910.  
  1911.     for (int j = 0; j < block_body -> block_symbol -> NumVariableSymbols(); j++)
  1912.         definite_visible_variables -> AddElement(block_body -> block_symbol -> VariableSym(j));
  1913.  
  1914.     DefiniteBlockStatements(block_body);
  1915.  
  1916.     //
  1917.     // For each final that has definitely been assigned a value in this block,
  1918.     // mark it appropriately.
  1919.     //
  1920.     BitSet &exit_set = definite_block_stack -> TopExitSet(*definitely_assigned_variables);
  1921.     for (int k = 0; k < finals.Length(); k++)
  1922.     {
  1923.         int index = block_body -> block_symbol -> max_variable_index + k;
  1924.         if (exit_set[index])
  1925.             finals[k] -> MarkDefinitelyAssigned();
  1926.     }
  1927.  
  1928.     //
  1929.     // For each final that may have possibly been assigned a value in this block,
  1930.     // mark it appropriately.
  1931.     //
  1932.     exit_set = definite_block_stack -> TopFinalExitSet(*possibly_assigned_finals);
  1933.     for (int l = 0; l < finals.Length(); l++)
  1934.     {
  1935.         int index = block_body -> block_symbol -> max_variable_index + l;
  1936.         if (exit_set[index])
  1937.             finals[l] -> MarkPossiblyAssigned();
  1938.     }
  1939.  
  1940.     definite_block_stack -> Pop();
  1941.     definite_block_stack -> Pop(); // remove NULL that was pushed to indicate that no method is available
  1942.  
  1943.     delete universe;
  1944.     delete definitely_assigned_variables;
  1945.     delete definite_block_stack;
  1946.     delete definite_try_stack;
  1947.     delete definite_final_assignment_stack;
  1948.     delete definite_visible_variables;
  1949.     delete possibly_assigned_finals;
  1950.  
  1951.     return;
  1952. }
  1953.  
  1954.  
  1955. void Semantic::DefiniteVariableInitializer(AstVariableDeclarator *variable_declarator, Tuple<VariableSymbol *> &finals)
  1956. {
  1957.     universe = new BitSet(finals.Length(), BitSet::UNIVERSE);
  1958.     definite_block_stack = NULL;
  1959.     definite_try_stack = NULL;
  1960.     definite_final_assignment_stack =  new DefiniteFinalAssignmentStack();
  1961.     definite_visible_variables = new SymbolSet(universe -> Size());
  1962.     definitely_assigned_variables = new BitSet(universe -> Size(), BitSet::EMPTY);
  1963.     possibly_assigned_finals = new BitSet(universe -> Size(), BitSet::EMPTY);
  1964.     for (int i = 0; i < finals.Length(); i++)
  1965.     {
  1966.         finals[i] -> SetLocalVariableIndex(i);
  1967.         if (finals[i] -> IsDefinitelyAssigned())
  1968.         {
  1969.             definitely_assigned_variables -> AddElement(i);
  1970.             possibly_assigned_finals -> AddElement(i);
  1971.         }
  1972.         else if (finals[i] -> IsPossiblyAssigned())
  1973.             possibly_assigned_finals -> AddElement(i);
  1974.         definite_visible_variables -> AddElement(finals[i]);
  1975.     }
  1976.  
  1977.     DefiniteVariableInitializer(variable_declarator);
  1978.     VariableSymbol *symbol = variable_declarator -> symbol;
  1979.     if (symbol -> ACC_FINAL())
  1980.         symbol -> MarkDefinitelyAssigned();
  1981.     //
  1982.     // Also, update any other finals that may have been initialized as
  1983.     // a side-effect in an assignment embedded within the initializer
  1984.     // expression.
  1985.     //
  1986.     BitSet &exit_set = *definitely_assigned_variables;
  1987.     for (int k = 0; k < finals.Length(); k++)
  1988.     {
  1989.         if (exit_set[k])
  1990.             finals[k] -> MarkDefinitelyAssigned();
  1991.     }
  1992.  
  1993.     delete universe;
  1994.     delete definitely_assigned_variables;
  1995.     delete definite_final_assignment_stack;
  1996.     delete definite_visible_variables;
  1997.     delete possibly_assigned_finals;
  1998.  
  1999.     return;
  2000. }
  2001.